package pr.lanmu.config.apijson;

import apijson.RequestMethod;
import apijson.orm.AbstractParser;
import apijson.orm.Parser;
import apijson.orm.SQLConfig;
import com.alibaba.fastjson.JSONObject;
import jakarta.servlet.http.HttpSession;
import lombok.Getter;

import java.util.HashMap;
import java.util.Map;

/**
 * 请求解析器
 * 具体见 <a href="https://github.com/Tencent/APIJSON/issues/38">...</a>
 *
 * @author Lemon
 */
@Getter
public class SqlParser extends AbstractParser<Long> {

    public static final Map<String, HttpSession> KEY_MAP;

    static {
        KEY_MAP = new HashMap<>();
    }

    private HttpSession session;
    private apijson.orm.FunctionParser functionParser;

    public SqlParser() {
        super();
    }

    public SqlParser(RequestMethod method) {
        super(method);
    }

    public Parser<Long> setSession(HttpSession session) {
        this.session = session;
        return this;
    }

    @Override
    public Parser<Long> createParser() {
        return new SqlParser();
    }

    @Override
    public apijson.orm.ObjectParser createObjectParser(JSONObject request, String parentPath, SQLConfig arrayConfig
            , boolean isSubquery, boolean isTable, boolean isArrayMainTable) throws Exception {
        return new ObjectParser(getSession(), request, parentPath, arrayConfig
                , isSubquery, isTable, isArrayMainTable).setMethod(getMethod()).setParser(this);
    }

    @Override
    public apijson.orm.FunctionParser createFunctionParser() {
        return new FunctionParser();
    }

    @Override
    public SQLConfig createSQLConfig() {
        return new SqlConfig();
    }

    @Override
    public apijson.orm.SQLExecutor createSQLExecutor() {
        return new SqlExecutor();
    }

    @Override
    public apijson.orm.Verifier<Long> createVerifier() {
        return new Verifier();
    }

    public Object onFunctionParse(String key, String function, String parentPath, String currentName, JSONObject currentObject, boolean containRaw) throws Exception {
        if (functionParser == null) {
            functionParser = createFunctionParser();
            functionParser.setMethod(getMethod());
            functionParser.setTag(getTag());
            functionParser.setVersion(getVersion());
            functionParser.setRequest(requestObject);
        }
        functionParser.setKey(key);
        functionParser.setParentPath(parentPath);
        functionParser.setCurrentName(currentName);
        functionParser.setCurrentObject(currentObject);

        return functionParser.invoke(function, currentObject, containRaw);
    }
}